define(['text!html/bookings.html', 'text!html/bookFlight.html', 'css!styles/bookings.css', 'js/navigationManager', 'js/serverWrapper', 'knockoutjs'], function (bookingsTemplate, bookFlightTemplate, _style, navigationManager, serverWrapper, ko) {
    return new function () {
        var presenter = this;

        var authenticationPresenterPromise = curl('js/authenticationPresenter');
        var profilePresenterPromise = curl('js/profilePresenter');

        function bookingViewModel(booking) {
            var self = this;

            self.id = ko.observable(booking._bookingId);
            self.date = ko.observable(booking._bookingDate);
            self.expanded = ko.observable(false);
            self.tickets = ko.observableArray();
            self.seats = ko.observableArray();

            var deffered = $.Deferred();
            serverWrapper
                .bookingSeats(self.id())
                .success(function (result) {
                    if (!result) return;
                    for (var i = 0; i < result.length; ++i) {
                        var seat = {
                            id: ko.observable(result[i].seat_id),
                            seatClass: ko.observable(result[i].seat_class),
                            seat: ko.observable(result[i].row + '' + result[i].column),
                            cost: ko.observable(result[i].cost)
                        };

                        self.seats.push(seat);
                    }

                    deffered.resolve();
                });

            serverWrapper
                .bookingTickets(self.id())
                .success(function (result) {
                    if (!result) return;
                    $.when(deffered.promise()).then(function () {
                        for (var i = 0; i < result.length; ++i) {
                            var ticket = {
                                id: ko.observable(result[i].ticket_id),
                                passport: ko.observable(result[i].passport_number),
                                name: ko.observable(result[i].first_name + ' ' + result[i].last_name),
                                seat: ko.observable()
                            };

                            for (var j = 0; j < self.seats().length; ++j) {
                                if (self.seats()[j].id() == result[i].seat_id) {
                                    ticket.seat(self.seats()[j]);
                                }
                            }

                            self.tickets.push(ticket);
                        }
                    });
                });

            self.bookingClick = function () {
                self.expanded(!self.expanded());
            };
        }

        function bookingsViewModel(bookings) {

            this.bookings = ko.observableArray();

            for (var i = 0; i < bookings.length; ++i) {
                this.bookings.push(new bookingViewModel(bookings[i]));
            }
        };

        function bookFlightViewModel(booking) {
            var self = this;

            self.userId = ko.observable(-1);
            self.seatClass = ko.observable(booking.name());
            self.availableSeatsCount = ko.observable(booking.seats());
            self.price = ko.observable(booking.price());
            self.flightId = ko.observable(booking.flightId());
            self.departAirport = ko.observable(booking.departAirport());
            self.arrivalAirport = ko.observable(booking.arrivalAirport());
            self.departDate = ko.observable(booking.departDate());
            self.airline = ko.observable(booking.airline());
            self.desiredSeatsCount = ko.observable(1);
            self.users = ko.observableArray();
            self.failureMessage = ko.observable();
            self.totalPrice = ko.computed(function () {
                return self.desiredSeatsCount() * self.price();
            });

            authenticationPresenterPromise.then(function (authenticationPresenter) {
                self.userId(authenticationPresenter.getUserID());
            });

            self.users.push(new userViewModel());

            var isNumber = function (n) {
                return !isNaN(parseFloat(n)) && isFinite(n);
            };

            ko.computed(function () {
                if (self.desiredSeatsCount() > self.availableSeatsCount()) {
                    self.desiredSeatsCount(self.availableSeatsCount());
                }

                if (self.desiredSeatsCount() == 0 || !isNumber(self.desiredSeatsCount())) {
                    self.desiredSeatsCount(1);
                }

                if (self.users().length != self.desiredSeatsCount()) {
                    if (self.users().length < self.desiredSeatsCount()) {
                        var iterations = self.desiredSeatsCount() - self.users().length;
                        for (var i = 0; i < iterations; ++i) {
                            self.users.push(new userViewModel());
                        }
                    }
                    else {
                        var iterations = self.users().length - self.desiredSeatsCount();
                        for (var i = 0; i < iterations; ++i) {
                            self.users.pop();
                        }
                    }
                }
            });

            self.book = function () {
                self.failureMessage(null);

                for (var i = 0; i < self.users().length; ++i) {
                    if (self.users()[i].firstName() == null ||
                        self.users()[i].firstName().length == 0 ||
                        self.users()[i].lastName() == null ||
                        self.users()[i].lastName().length == 0 ||
                        self.users()[i].passport() == null ||
                        self.users()[i].passport().length == 0 ||
                        !isNumber(self.users()[i].passport()) ||
                        self.users()[i].creditCard() == null ||
                        self.users()[i].creditCard().length == 0 ||
                        !isNumber(self.users()[i].creditCard()) ||
                        self.users()[i].creditExpiration() == null ||
                        self.users()[i].creditExpiration().length == 0) {

                        self.failureMessage('All fields are required');
                        return;
                    }
                }

                serverWrapper
                    .bookFlight(self)
                    .success(function () {
                        alert('Booking sucessfully completed!');
                        profilePresenterPromise.then(function (profilePresenter) {
                            profilePresenter.bind();
                        });
                    })
                    .error(function () {
                        self.failureMessage('Fatal error occured');
                    });
            };
        };

        function userViewModel() {
            this.firstName = ko.observable();
            this.lastName = ko.observable();
            this.passport = ko.observable();
            this.creditCard = ko.observable();
            this.creditExpiration = ko.observable();
        };

        presenter.bind = function (bookings) {
            navigationManager.load('bookings', bookingsTemplate, new bookingsViewModel(bookings));
        };

        presenter.book = function (booking) {
            navigationManager.load('bookFlight', bookFlightTemplate, new bookFlightViewModel(booking));
        };
    };
});